/*
 * @Author       : Joel
 * @Date         : 2023-09-01 11:52:38
 * @LastEditors: Joel
 * @LastEditTime: 2025-04-17 10:06:04
 * @FilePath: /gd32f303cct6/usr/src/user_timer.c
 * @Description  :
 * Copyright 2023 Siliten, All Rights Reserved.
 * 2023-09-01 11:52:38
 */
/* 包含头文件代码 */
#include "user_timer.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/* 私有(仅本源文件内使用)宏、枚举、结构体的定义 */

typedef struct _userTimer_
{
    // 使能定时器
    uint8_t en;
    // 进入中断后的计数值
    uint32_t timeCntMs;
    // 计时阀值
    uint32_t timeoutMs;
    // 回调函数的形参
    void *arg;
    // 回调函数
    void (*cb)(void *);
} userTimer_t;

static userTimer_t userTimer[TINERID_MAX];

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/* 内部函数(即 static 修饰)的声明 */

/*******************************************************************************
 * Variables
 ******************************************************************************/

/* 所有全局变量(外部，静态，常量，指针)的定义 */

/*******************************************************************************
 * Code
 ******************************************************************************/

/* 所有函数(外部，内部)的定义 */
static void User_Timer_Hw_Init(void)
{
    timer_parameter_struct timerInitpara;
    rcu_periph_clock_enable(RCU_TIMER4);

    timer_deinit(TIMER4);
    timer_struct_para_init(&timerInitpara);
    timerInitpara.prescaler = TIMER4_PRESCALER;
    timerInitpara.alignedmode = TIMER_COUNTER_EDGE;
    timerInitpara.counterdirection = TIMER_COUNTER_UP;
    timerInitpara.period = BASE_TIMER4_MS; // 1ms;
    timerInitpara.clockdivision = TIMER_CKDIV_DIV1;
    timerInitpara.repetitioncounter = 0; // 每次溢出都产生更新是件
    timer_init(TIMER4, &timerInitpara);

    // 设置全局中断组
    timer_interrupt_enable(TIMER4, TIMER_INT_UP);
    timer_enable(TIMER4);

    // 中断抢占优先级和响应优先级配置，数值越小优先级越高
    nvic_irq_enable(TIMER4_IRQn, 1U, 0);
}

/**
 * @brief  This function handles TIMERx interrupt request.
 * @param  None
 * @retval None
 */
void TIMER4_IRQHandler(void)
{
    int i = 0;
    /* here check timer interrupt bit */
    if (SET == timer_interrupt_flag_get(TIMER4, TIMER_FLAG_UP))
    {
        /* here clear timer interrupt bit */
        timer_interrupt_flag_clear(TIMER4, TIMER_FLAG_UP);
        for (i = 0; i < TINERID_MAX; i++)
        {
            if (userTimer[i].en && userTimer[i].cb != NULL)
            {
                userTimer[i].timeCntMs++;
                if (userTimer[i].timeCntMs >= userTimer[i].timeoutMs)
                {
                    userTimer[i].timeCntMs = 0;
                    /* 执行回调函数 */
                    userTimer[i].cb(userTimer[i].arg);
                }
            }
            else
            {
                userTimer[i].timeCntMs = 0;
            }
        }
    }
}

void User_Timer_Init(void)
{
    printf("User_Timer_Init...\r\n");
    int i = 0;
    User_Timer_Hw_Init();
    for (i = 0; i < TINERID_MAX; i++)
    {
        userTimer[i].en = 0;
        userTimer[i].timeCntMs = 0;
        userTimer[i].timeoutMs = 0;
        userTimer[i].arg = NULL;
        userTimer[i].cb = NULL;
    }
    return;
}

void User_Timer_Config(uint8_t timerId, uint32_t timeoutMs, void (*cb)(void *), void *arg)
{

    userTimer[timerId].cb = cb;
    userTimer[timerId].arg = arg;
    userTimer[timerId].timeoutMs = timeoutMs;
    return;
}

void User_Timer_Start(uint8_t timerId)
{
    userTimer[timerId].en = 1;
    return;
}

void User_Timer_Stop(uint8_t timerId)
{
    userTimer[timerId].en = 0;
    return;
}

void User_Timer_Clear(uint8_t timerId)
{
    userTimer[timerId].en = 0;
    userTimer[timerId].cb = NULL;
    userTimer[timerId].arg = NULL;
    userTimer[timerId].timeoutMs = 0;
    userTimer[timerId].timeCntMs = 0;
    return;
}
/* el psy congroo */
